package com.agenda.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import com.agenda.comum.ReceberInformacao;
import com.agenda.model.RequisicaoEnum;
import com.agenda.model.Usuario;
import com.agenda.model.UsuarioIP;
import com.agenda.server.listeners.ClienteAdicionadoListener;
import com.agenda.server.net.RequisicaoThread;

public class Servidor {

	private static HashMap<RequisicaoEnum, ReceberInformacao> RECEBEDORES = new HashMap<RequisicaoEnum, ReceberInformacao>();

	private ServerSocket server;

	private HashMap<Usuario, Socket> usuariosOnLine = new HashMap<Usuario, Socket>();

	private int porta;

	private boolean aguardarConexoes = true;

	private ClienteAdicionadoListener adicionadoListener;

	private static Servidor INSTANCIA;

	private Servidor() {

	}

	public void criarServidor() throws IOException {
		server = new ServerSocket(porta);
	}

	public void aguardarConexoes() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				while (aguardarConexoes) {
					try {
						Socket sck = server.accept();
						if (sck != null) {
							if (adicionadoListener != null)
								adicionadoListener.adicionou(sck);
							new Thread(new RequisicaoThread(sck)).start();
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}

	public void setPorta(int porta) {
		this.porta = porta;
	}

	public void setClienteAdicionadoListener(ClienteAdicionadoListener clienteAdicionadoListener) {
		this.adicionadoListener = clienteAdicionadoListener;
	}

	public static void registrarRecebedor(RequisicaoEnum requisicao, ReceberInformacao recebedor) {
		RECEBEDORES.put(requisicao, recebedor);
	}

	public static ReceberInformacao getRecebedor(RequisicaoEnum requisicao) {
		return RECEBEDORES.get(requisicao);
	}

	public void adicionarUsuarioOnLine(Usuario usuario, Socket sck) {
		usuariosOnLine.put(usuario, sck);
	}

	public void removerUsuarioOnLine(Usuario usuario) {
		usuariosOnLine.remove(usuario);
	}

	public static Servidor getInstancia() {
		if (INSTANCIA == null)
			INSTANCIA = new Servidor();

		return INSTANCIA;
	}

	public ArrayList<Usuario> getUsuariosOnline() {
		return new ArrayList<Usuario>(usuariosOnLine.keySet());
	}

	public ArrayList<UsuarioIP> retornarUsuariosIP(ArrayList<Usuario> convidados) {
		ArrayList<UsuarioIP> usuariosIP = new ArrayList<UsuarioIP>();

		for (Usuario usuario : convidados) {
			Socket endereco = usuariosOnLine.get(usuario);

			if (endereco != null) {
				UsuarioIP userIP = new UsuarioIP();

				userIP.setUsuario(usuario);
				userIP.setIp(endereco.getInetAddress().getHostAddress());
				usuariosIP.add(userIP);
			}
		}

		return usuariosIP;
	}
}
